//****************************************************
// Porman Project 2
// Filename: CWordSystem.h
// Date: 2009/08/09
// Author: KengYu Lin
// Modify:
//****************************************************
#ifndef _CWORDSYSTEM_H
#define _CWORDSYSTEM_H
#include <map>
#include <vector>
#include "CGLDef.h"

namespace Porman
{

namespace GL
{

//-----------------------------
// class CTGAImg
//-----------------------------
class CTGAImg
{
public:
	CTGAImg();
	~CTGAImg();
	int load(const char* szFilename);
	int getBPP();
	int getWidth();
	int getHeight();
	unsigned char* getImg(void);       // Return a pointer to image data
	unsigned char* getPalette(void);   // Return a pointer to VGA palette
	void flipImg();
	bool downSampling(void);

private:
	// Internal workers
	int  _readHeader( void );
	int  _loadRawData( void );
	int  _loadTgaRLEData( void );
	int  _loadTgaPalette( void );
	void _BGRtoRGB( void );
	unsigned char* _getPixel( int x, int y );
 
	short int m_iWidth,m_iHeight,m_iBPP;
	unsigned long m_lImageSize;
	char m_bEnc;
	unsigned char *m_pImage, *m_pPalette, *m_pData;
};

//-----------------------------
// class CWordTable
//-----------------------------
class CWordTable
{
public:
    PGL_API CWordTable( void );
    PGL_API virtual ~CWordTable();

    PGL_API void parserString( const char* String, int& iBufferSizeInByte, int& iIBufferSizeInByte );
    PGL_API void copyStringFrom( float* ppOutVBuffer, int iCopyMaxVBSizeInByte, unsigned short* ppOutIBuffer, int iCopyMaxIBSizeInByte );
    PGL_API int loadTGAImg( const char* sFilename, int iWidthOfTxt = 32, int iHeightOfTxt = 32 );
    PGL_API int getImgSize( void );
	PGL_API int getImgWidth( void );
	PGL_API int getImgHeight( void );
    PGL_API int getBPP( void ); //BPP: Bytes per Pixel
    PGL_API unsigned char* getImgData(void); // Return a pointer to image data

protected:
    struct SVertex
    {
        SVertex( void ) { m_fX = m_fY = m_fZ = 0; m_fU = m_fV =0; }
        SVertex& operator= ( const SVertex& l )
        {
            m_fX = l.m_fX; m_fY = l.m_fY; m_fZ = l.m_fZ;
            m_fU = l.m_fU; m_fV = l.m_fV;
            return *this;
        }

        float m_fX, m_fY, m_fZ; //World coord.
        float m_fU, m_fV;       //Texture coord.
    };

    class CText
    {
    public:
        //-------------------------------------
        // Z value always zero!! (LOCAL SPACE):
        //         y
        // V0(0,0) |      V2(0,2)
        //   ------*-----*--------------->x
        //         |\    |
        //         | \   |
        //         |  \  |
        //         |   \ |
        //V1(0,-2) *----\* V3(2,-2)
        //         |
        //--------------------------------------
        CText( void );
        CText( float fWidth, float fHeight );
        virtual ~CText( void ) {}

        void setASCII_ID( char cChar ) { m_uiASCII_ID = static_cast<unsigned int>(cChar); }
        char getASCII_ID( void )       { return static_cast<char>(m_uiASCII_ID); }

        SVertex* getVertex( int iIndex ) { assert( iIndex >= 0 && iIndex <4 ); return &m_Vertexs[iIndex]; }

        float setWidth( float fWidth )   { m_fWidth = fWidth; _calVertexPos(); }
        float setHeight( float fHeight ) { m_fHeight = fHeight; _calVertexPos(); }
        float getWidth( void )  { return m_fWidth; }
        float getHeight( void ) { return m_fHeight; }

    protected:
        void _calVertexPos( void );

        SVertex m_Vertexs[4];
        unsigned int m_uiASCII_ID;
        float m_fWidth, m_fHeight;
    };

protected:
    void _initial( void );
    void _uninitial( void );
    void _calTxtCoord( void );

    int m_iWIDTH_OF_TEXTURE;
    int m_iHEIGHT_OF_TEXTURE;
    int m_iWIDTH_OF_TXT;
    int m_iHEIGHT_OF_TXT;
    int m_iPER_PIXEL_BYTES;

    CTGAImg m_TGAImgLoader;
    std::map<unsigned int, CText*> m_mapASCIITable;
    std::vector<CText*> m_vectWord;
    unsigned int m_uiASCIITexture[60000];
    IMG_RESULT m_eLoadingState;
};

//-----------------------------
// class CWordSystem
//-----------------------------
class CWordSystem
{
    friend class CRenderDevice;
protected:
    CWordSystem( void );
    ~CWordSystem( void );

    bool initial( CRenderDevice* pRenderDevice, const char* sFilename );
    void uninitial( void );
    void setOrthoL( float left, float right, float bottom, float top, float nearVal, float farVal, float* pM );
    void mulMatrix( const float* pM1, const float* pM2, float* pOut );

protected:
    CRenderDevice*       m_pRenderDeviceRef;
    CWordTable           m_WordTable;
    CVertexDeclObject*   m_pVDeclObj;
    CShaderObject*       m_pVSObj;
    CShaderObject*       m_pPSObj;
    CTexture2DObject*    m_pTextObj;
    CAlphaStateObject    m_AlphaStateObj;

    CSamplerState        m_Sampler;
};

}//End namespace GL

}//End namespace Porman

#endif